﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
using GpCommon;
using GpCommon.Helpers;
using GpCommon.Models;
using GPSpeedView.GPHelpers;
using GPSpeedView.Models;
using GPSpeedView.Views;
using Microsoft.Win32;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using Prism;
using Prism.Mvvm;

namespace GPSpeedView
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public static Dictionary<int, MainWindow> DicMainView = new Dictionary<int, MainWindow>();
        public static MainWindow mainView;
        private MainViewModel m_ViewModel;
        public int m_ViewType = 0;
        public string m_Time;
        private KeyboardHook _keyboardHook;


        public static void ShowView(int viewType)
        {
            MainWindow view = null;
            if (DicMainView.ContainsKey(viewType))
            {
                view = DicMainView[viewType];
                view.Close();
                return;
            }
            else
            {
                view = new MainWindow(viewType);
                DicMainView.Add(viewType, view);
                if (viewType == 1)
                {
                    view.Left = mainView.Left - view.Width - 20;
                    view.Top = mainView.Top;
                }
                else if (viewType == 2)
                {
                    view.Left = mainView.Left;
                    view.Top = mainView.Top - view.Height - 20;
                }
            }
            view.Activate();
            if (view.WindowState == WindowState.Minimized)
            {
                view.WindowState = WindowState.Normal;
            }
            view.Owner = mainView;
            view.Show();
        }

        #region 构造函数
        public MainWindow()
        {
            InitializeComponent();
            m_ViewModel = new MainViewModel(this);
            this.DataContext = m_ViewModel;
            m_ViewModel.OrderBy = SortType.ACCER;
            ColumnStatus.Visibility = Visibility.Visible;
            mainView = this;

            _keyboardHook = new KeyboardHook();
            _keyboardHook.SetHook();
            _keyboardHook.SetOnKeyDownEvent(Win32_Keydown);
            _keyboardHook.SetOnKeyUpEvent(Win32_Keyup);

        }

        // viewType  1: 历史选股  2: 自选股   3:机会股
        private MainWindow(int viewType)
        {
            m_ViewType = viewType;
            InitializeComponent();
            m_ViewModel = new MainViewModel(this);
            this.DataContext = m_ViewModel;
            _keyboardHook = new KeyboardHook();
            _keyboardHook.SetHook();
            _keyboardHook.SetOnKeyDownEvent(Win32_Keydown);
            _keyboardHook.SetOnKeyUpEvent(Win32_Keyup);
            if (viewType == 1)
            {
                this.Title = "盘中涨停票";
                SettingMenuItem.Visibility = Visibility.Collapsed;
                SortSettingMenuItem.Visibility = Visibility.Collapsed;
                RemoveListItem.Visibility = Visibility.Collapsed;
                ShowTodayItem.Visibility = Visibility.Collapsed;
                ColumnACCERInFive.Visibility = Visibility.Collapsed;
                ColumnACCER.Visibility = Visibility.Collapsed;
                SelectTimeItem.Visibility = Visibility.Visible;
                CheckColumn.Visibility = Visibility.Visible;

                RecordTimeCol.Visibility = Visibility.Visible;
                RecordPriceCol.Visibility = Visibility.Visible;
                RecordMarkupCol.Visibility = Visibility.Visible;
                this.Width = 800;
                AddTimeItems();

            }
            else if (viewType == 2)
            {
                this.Title = "自选";
                SettingMenuItem.Visibility = Visibility.Collapsed;
                SortSettingMenuItem.Visibility = Visibility.Collapsed;
                RemoveListItem.Visibility = Visibility.Collapsed;
                ShowTodayItem.Visibility = Visibility.Collapsed;
                ColumnACCERInFive.Visibility = Visibility.Collapsed;
                ColumnACCER.Visibility = Visibility.Collapsed;
                LockListItem.Visibility = Visibility.Collapsed;
                CheckColumn.Visibility = Visibility.Visible;

                LockRow.Height = new GridLength(30);
            }
            else if (viewType == 3)
            {
                this.Title = "机会";
                SettingMenuItem.Visibility = Visibility.Collapsed;
                SortSettingMenuItem.Visibility = Visibility.Collapsed;
                RemoveListItem.Visibility = Visibility.Collapsed;
                ShowTodayItem.Visibility = Visibility.Collapsed;
                ColumnACCERInFive.Visibility = Visibility.Collapsed;
                ColumnACCER.Visibility = Visibility.Collapsed;
                LockListItem.Visibility = Visibility.Collapsed;
                CheckColumn.Visibility = Visibility.Visible;
                SelectedTimeRow.Height = new GridLength(30);
                SettingTime();
            }
            else
            {
                m_ViewModel.OrderBy = SortType.ACCER;
                ColumnStatus.Visibility = Visibility.Visible;
            }

        }

        #endregion

        #region 私有方法
        private void AddTimeItems()
        {
            foreach (var item in ConfigData.MidFastUpGPs.Keys)
            {
                MenuItem menu = new MenuItem();
                menu.Header = item;
                menu.Click += SelectTimeItem_Click;
                SelectTimeItem.Items.Add(menu);
            }
        }

        private void SettingTime()
        {
            // 获取两年的信息
            var dayList = GpLocalDataHelper.GetLocalHistoryDayInfoByCode(DateTime.Now.Year - 1, CommonData.TargetCode);
            dayList.AddRange(GpLocalDataHelper.GetLocalHistoryDayInfoByCode(DateTime.Now.Year, CommonData.TargetCode));

            if (dayList.Count > 1)
            {
                var startTime = dayList[0].Time;
                datePicker.DisplayDateStart = startTime;
                datePicker.DisplayDateEnd = DateTime.Now;
                while (startTime.CompareTo(DateTime.Now) < 0)
                {
                    if (dayList.Find(x => x.Time == startTime) == null)
                    {
                        datePicker.BlackoutDates.Add(new CalendarDateRange(startTime));
                    }
                    startTime = startTime.AddDays(1);
                }
            }
        }
        #endregion

        #region 命令执行方法
        /// <summary>
        /// 点击历史数据时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectTimeItem_Click(object sender, RoutedEventArgs e)
        {
            var menu = sender as MenuItem;
            m_Time = menu.Header.ToString();
            m_ViewModel.InitDataForOldGps();
        }
        /// <summary>
        /// 点击设置界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SettingMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ConfigView view = new ConfigView();
            view.Show();
        }
        /// <summary>
        /// 点击打开移除列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RemoveListItem_Click(object sender, RoutedEventArgs e)
        {
            RemoveListView view = new RemoveListView();
            view.Owner = mainView;
            view.Show();
        }

        /// <summary>
        /// 点击删除按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CloseBtn_Click(object sender, RoutedEventArgs e)
        {
            if (GpDataGrid.SelectedItem != null)
            {
                var ent = GpDataGrid.SelectedItem as ViewEntity;

                var checkList = m_ViewModel.GPData.ToList().FindAll(x => x.IsChecked);
                checkList.Add(ent);
                if (m_ViewType == 1)
                {
                    if (MessageBox.Show("确定删除勾选项？", "提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                    {
                        if (ConfigData.MidFastUpGPs.ContainsKey(m_Time))
                        {
                            foreach (var item in checkList)
                            {
                                ConfigData.MidFastUpGPs[m_Time].RemoveAll(x => x.Code == item.Code);
                            }
                        }

                        m_ViewModel.InitDataForOldGps();
                    }
                }
                else if (m_ViewType == 2)
                {
                    if (MessageBox.Show("确定删除勾选项？", "提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                    {
                        foreach (var item in checkList)
                        {
                            ConfigData.LockGPs.RemoveAll(x => x == item.Code);
                        }
                        m_ViewModel.InitDataForLockGps();
                    }
                }
                else if (m_ViewType == 3)
                {
                    if (MessageBox.Show("确定删除勾选项？", "提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                    {
                        foreach (var item in checkList)
                        {
                            ConfigData.HighGpDataInfo.RemoveAll(x => x.Code == item.Code);
                        }
                        m_ViewModel.InitHighChanceGps();
                    }
                }
                else
                {
                    if (!ConfigData.FlagGps.Contains(ent.Name))
                    {
                        ConfigData.FlagGps.Add(ent.Name);
                    }
                }
            }
        }
        /// <summary>
        /// 点击添加自选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LockBtn_Click(object sender, RoutedEventArgs e)
        {
            if (GpDataGrid.SelectedItem != null)
            {
                var ent = GpDataGrid.SelectedItem as ViewEntity;

                if (!ConfigData.LockGPs.Contains(ent.Code))
                {
                    ConfigData.LockGPs.Add(ent.Code);
                }
            }
        }
        /// <summary>
        /// 点击显示历史数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ShowTodayItem_Click(object sender, RoutedEventArgs e)
        {
            ShowView(1);
        }

        /// <summary>
        /// 界面关闭保存处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void main_Closed(object sender, EventArgs e)
        {
            DataHelper.WriteMidFastUpGPs();
            DataHelper.WriteAnalyseGPs();
            DataHelper.WriteLockGps();
            DataHelper.WriteConfigData();
            if (DicMainView.ContainsKey(m_ViewType))
            {
                DicMainView.Remove(m_ViewType);
                m_ViewModel.m_View = null;
                m_ViewModel = null;
            }

            _keyboardHook.UnHook();
        }
        /// <summary>
        /// 点击显示自选数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LockListItem_Click(object sender, RoutedEventArgs e)
        {
            ShowView(2);
        }
        /// <summary>
        /// 点击打开对应网页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void browenBtn_Click(object sender, RoutedEventArgs e)
        {
            if (GpDataGrid.SelectedItem != null)
            {
                var ent = GpDataGrid.SelectedItem as ViewEntity;

                string path = @"C:\Program Files (x86)\Microsoft\Edge Beta\Application\msedge.exe";

                ProcessStartInfo psi = new ProcessStartInfo { FileName = path, Arguments = UrlHelper.GetUrlForSingleGpBrowenPage(ent.Code) };
                Process.Start(psi);
            }
        }
        private void browenMSBtn_Click(object sender, RoutedEventArgs e)
        {
            if (GpDataGrid.SelectedItem != null)
            {
                var ent = GpDataGrid.SelectedItem as ViewEntity;

                string time = DateTime.Now.ToShortDateString();
                if (m_ViewType == 1)
                {
                    time = m_Time;
                }
                string url = UrlHelper.GetUrlForSingleGpDetailDataBrowenPage(ent.Code, time);
                string path = @"C:\Program Files (x86)\Microsoft\Edge Beta\Application\msedge.exe";

                ProcessStartInfo psi = new ProcessStartInfo { FileName = path, Arguments = url };
                Process.Start(psi);
            }
        }
        /// <summary>
        /// 点击导出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ExportListItem_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 创建一个 Bitmap 对象，表示画布
                Bitmap bitmap = new Bitmap(1000, 1000);

                // 创建一个 Graphics 对象，用于在 Bitmap 上绘图
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    // 设置画布背景色
                    graphics.Clear(System.Drawing.Color.White);

                    // 设置绘图字体和颜色
                    Font font = new Font("Arial", 18);
                    SolidBrush brush = new SolidBrush(System.Drawing.Color.Black);

                    float y = 10f; // 纵坐标

                    float x = 10f;
                    // 在画布上逐个绘制成语
                    foreach (ViewEntity ent in m_ViewModel.GPData)
                    {
                        graphics.DrawString(ent.Code, font, brush, new PointF(x, y));
                        x += 200;
                        if (x > 1000)
                        {
                            x = 10;
                            y += 40;
                        }
                    }
                }

                // 保存绘制好的图像为文件
                bitmap.Save(@"output.png", ImageFormat.Png);

                // 释放资源
                bitmap.Dispose();
            }
            catch (Exception)
            {
            }
            MessageBox.Show("导出成功");
        }
        /// <summary>
        /// 点击加载历史数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void LoadHistoryDataItem_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("确定要加载历史数据吗？", "提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                LoadHistoryExec(null);
            }
        }
        public void LoadHistoryExec(object obj)
        {
            m_ViewModel.ClearWorkerHandler();
            m_ViewModel.worker.DoWork += m_ViewModel.Worker_DoWork_LoadHis;
            m_ViewModel.worker.RunWorkerAsync();
        }
        public void LoadHistoryExecute()
        {
            AlGpHelper.LoadHistoryGpInfo(m_ViewModel.worker);
        }
        /// <summary>
        /// 添加自选gp
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddBtn_Click(object sender, RoutedEventArgs e)
        {
            var gps = GpLocalDataHelper.GetValidGps();
            string code = addCodeBox.Text;
            if (!int.TryParse(code, out int i))
            {
                var gp = gps.Find(x => x.Item2 == code);
                if (gp == null)
                {
                    MessageBox.Show("所填名称无效");
                    return;
                }
                code = gp.Item1;
            }
            if (string.IsNullOrEmpty(code))
                return;
            if (ConfigData.LockGPs.Contains(code))
            {
                MessageBox.Show("已在自选列表");
            }
            else
            {
                var codes = GpLocalDataHelper.GetValidGpCodes();
                if (!codes.Contains(code))
                {
                    MessageBox.Show("所填代号无效");
                }
                else
                {
                    ConfigData.LockGPs.Add(code);
                    m_ViewModel.InitDataForLockGps();
                }
            }
            addCodeBox.Text = "";
        }

        /// <summary>
        /// 点击显示分时数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GpDataGrid_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (GpDataGrid.SelectedItem != null)
            {
                var ent = GpDataGrid.SelectedItem as ViewEntity;
                GPDetailView m_GPDetailView = null;
                if (m_ViewType == 0 || m_ViewType == 2)
                {
                    m_GPDetailView = new GPDetailView(ent.Code);
                }
                else if (m_ViewType == 1)
                {
                    m_GPDetailView = new GPDetailView(ent.Code, DateTime.Parse(m_Time));
                }
                else if (m_ViewType == 3)
                {
                    m_GPDetailView = new GPDetailView(ent.Code, m_ViewModel.SelectedTime);
                }
                m_GPDetailView.Owner = mainView;
                m_GPDetailView.ShowView();
            }
        }
        /// <summary>
        /// 一键添加今日涨停股到自选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OneKeyToAddTop_Click(object sender, RoutedEventArgs e)
        {
            DateTime now = DateTime.Now;
            DateTime tdStopTime = now.Date + ConfigData.GpStopTime;

            if (DateTime.Compare(now, tdStopTime) < 0)
            {
                MessageBox.Show("请在收盘后进行一键操作");
                return;
            }
            try
            {
                Tuple<int, List<ViewEntity>> tuple = null;
                DateTime tempTime = DateTime.Now;
                tuple = GetTopData(tempTime, true).Result;
                while (tuple == null)
                {
                    tempTime = tempTime.AddDays(-1);
                    tuple = GetTopData(tempTime, true).Result;
                }

                tuple = GetTopData(tempTime, true, tuple.Item1).Result;
                foreach (var item in tuple.Item2)
                {
                    if (!ConfigData.LockGPs.Contains(item.Code))
                        ConfigData.LockGPs.Add(item.Code);
                }
                m_ViewModel.InitDataForLockGps();
            }
            catch (Exception ex)
            {
                MessageBox.Show("获取失败");
            }
        }
        /// <summary>
        /// 获取涨停数据
        /// </summary>
        /// <param name="day"></param>
        /// <param name="isToday"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task<Tuple<int, List<ViewEntity>>> GetTopData(DateTime time, bool isToday, int count = 20)
        {
            string url = UrlHelper.GetUrlForTodayTopGps(time, count);
            if (!isToday)
            {
                url = UrlHelper.GetUrlForYesTodayTopGps(time, count);
            }

            int size = 20;
            List<ViewEntity> ents = new List<ViewEntity>();
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
                if (response.IsSuccessStatusCode)
                {
                    response.EnsureSuccessStatusCode();
                    string htmlContent = response.Content.ReadAsStringAsync().Result;
                    if (!string.IsNullOrEmpty(htmlContent))
                    {
                        JObject jobject = JObject.Parse(htmlContent);
                        if (string.IsNullOrEmpty(jobject["data"].ToString())) return null;
                        var childrens = jobject["data"]["pool"].Children();
                        string totalStr = jobject["data"]["tc"].ToString();
                        if (!string.IsNullOrEmpty(totalStr))
                        {
                            int.TryParse(totalStr, out size);
                        }

                        foreach (var item in childrens)
                        {
                            ViewEntity ent = new ViewEntity();
                            ent.Code = item["c"].ToString();
                            ent.Name = item["n"].ToString();
                            ent.CurPrice = float.TryParse(item["p"].ToString(), out float curPrice) ? curPrice / 1000.0f : 0.0f;
                            ent.CurMarkUp = float.TryParse(item["zdp"].ToString(), out float curMarkup) ? (float)Math.Round(curMarkup, 2, MidpointRounding.AwayFromZero) : 0.0f;
                            ents.Add(ent);
                        }
                    }
                }
            }
            return new Tuple<int, List<ViewEntity>>(size, ents);
        }
        private void AiAutoItem_Click(object sender, RoutedEventArgs e)
        {
            AIAutoHandleView view = new AIAutoHandleView();
            view.Show();
        }
        /// <summary>
        /// 导入历史五分分时数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImportHis5MSItem_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog folderDialog = new System.Windows.Forms.FolderBrowserDialog();
            if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string folderPath = folderDialog.SelectedPath;
                string[] files = Directory.GetFiles(folderPath, "*.lc5", SearchOption.AllDirectories);
                if (files.Length == 0)
                {
                    MessageBox.Show("所选目录下未找到lc5文件。");
                    return;
                }
                m_ViewModel.SelectedFiles = files;
                m_ViewModel.ClearWorkerHandler();
                m_ViewModel.worker.DoWork += m_ViewModel.Worker_DoWork_ImportHis5MS;

                m_ViewModel.worker.RunWorkerAsync();
            }
        }
        /// <summary>
        /// 导入历史1分分时数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImportHis1MSItem_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog folderDialog = new System.Windows.Forms.FolderBrowserDialog();
            if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string folderPath = folderDialog.SelectedPath;
                string[] files = Directory.GetFiles(folderPath, "*.lc1", SearchOption.AllDirectories);
                if (files.Length == 0)
                {
                    MessageBox.Show("所选目录下未找到lc1文件。");
                    return;
                }
                m_ViewModel.SelectedFiles = files;
                m_ViewModel.ClearWorkerHandler();
                m_ViewModel.worker.DoWork += m_ViewModel.Worker_DoWork_ImportHis1MS;

                m_ViewModel.worker.RunWorkerAsync();
            }
        }
        /// <summary>
        /// 更新股票列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UpdateGpListItem_Click(object sender, RoutedEventArgs e)
        {
            m_ViewModel.UpdateGpListExecute();
        }
        private void TestItem_Click(object sender, RoutedEventArgs e)
        {
            TestBtnView view = new TestBtnView();
            view.Show();
            //if (m_ViewModel.dispatcherTimer.IsEnabled)
            //{
            //    m_ViewModel.dispatcherTimer.Stop();
            //    m_ViewModel.backDataTimer.Stop();
            //}
            //else
            //{
            //    m_ViewModel.dispatcherTimer.Start();
            //    m_ViewModel.backDataTimer.Start();
            //}
            //m_ViewModel.ClearWorkerHandler();
            //m_ViewModel.worker.DoWork += m_ViewModel.Worker_DoWork_Test;
            //m_ViewModel.worker.RunWorkerAsync();
        }

        private void ShowInfoItem_Click(object sender, RoutedEventArgs e)
        {
            GpInfoView view = new GpInfoView();
            view.Show();
        }
        private void ShowTodayHighItem_Click(object sender, RoutedEventArgs e)
        {
            ShowView(3);
        }
        private void datePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            if (datePicker.SelectedDate != null)
            {
                m_ViewModel.SelectedTime = (DateTime)datePicker.SelectedDate;
            }
            else
            {
                m_ViewModel.SelectedTime = DateTime.Now;
            }
        }
        private void IsPrePriceCheck_Checked(object sender, RoutedEventArgs e)
        {
            m_ViewModel.IsCheckPrePrice = true;
        }

        private void IsPrePriceCheck_Unchecked(object sender, RoutedEventArgs e)
        {
            m_ViewModel.IsCheckPrePrice = false;
        }

        private void Fst1PlateItem_Click(object sender, RoutedEventArgs e)
        {
            ConfigData.IsFst1PlateMode = !ConfigData.IsFst1PlateMode;
            Fst1PlateItem.Background = ConfigData.IsFst1PlateMode ? new SolidColorBrush(Colors.LightBlue) : new SolidColorBrush(Colors.White);
        }
        #endregion

        #region 全局键盘
        private Key _lastKey = Key.None;

        private void Win32_Keydown(Key key)
        {
            if (key == Key.LeftAlt)
            {
                _lastKey = key;
            }
            else if (_lastKey == Key.LeftAlt && key == Key.A)
            {
                if (this.Visibility == Visibility.Visible)
                {
                    this.Visibility = Visibility.Hidden;
                }
                else
                {
                    this.Visibility = Visibility.Visible;
                }
            }
            else
            {
                _lastKey = Key.None;
            }
        }
        private void Win32_Keyup(Key key)
        {
            if (key == Key.LeftAlt)
            {
                _lastKey = Key.None;
            }
        }

        #endregion
    }

    public class MainViewModel : BindableBase
    {
        public MainWindow m_View;
        private System.Threading.SynchronizationContext synContent = null;
        public DispatcherTimer dispatcherTimer = new DispatcherTimer(DispatcherPriority.Render);
        public Timer backDataTimer = new Timer();
        public BackgroundWorker worker;
        private string url1ForACCER = $"http://74.push2.eastmoney.com/api/qt/clist/get?&pn=1&pz={ConfigData.MaxFlashGpCount}&po=1&np=1&fltt=2&invt=2&wbp2u=|0|0|0|web&fid=f22&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048&fields=f2,f3,f12,f14,f20,f22,f11";
        private string url1ForACCERInFive = $"http://74.push2.eastmoney.com/api/qt/clist/get?&pn=1&pz={ConfigData.MaxFlashGpCount}&po=1&np=1&fltt=2&invt=2&wbp2u=|0|0|0|web&fid=f11&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048&fields=f2,f3,f12,f14,f20,f22,f11";

        private bool hasWrited = false;
        private ObservableCollection<ViewEntity> m_GPData = new ObservableCollection<ViewEntity>();

        public string[] SelectedFiles;
        public DateTime SelectedTime;
        public bool IsCheckPrePrice;

        public ObservableCollection<ViewEntity> GPData
        {
            get { return m_GPData; }
            set 
            { 
                m_GPData = value;
                RaisePropertyChanged();
            }
        }

        private SortType m_OrderBy;

        public SortType OrderBy
        {
            get { return m_OrderBy; }
            set 
            { 
                m_OrderBy = value;
                if(m_OrderBy == SortType.ACCER)
                {
                    m_View.ColumnACCER.Visibility = Visibility.Visible;
                    m_View.ColumnACCERInFive.Visibility = Visibility.Collapsed;
                }
                else
                {
                    m_View.ColumnACCER.Visibility = Visibility.Collapsed;
                    m_View.ColumnACCERInFive.Visibility = Visibility.Visible;
                }
                RaisePropertyChanged();
            }
        }

        public string OldListTime { get; set; }

        private bool m_IsAllChecked;

        public bool IsAllChecked
        {
            get { return m_IsAllChecked; }
            set 
            { 
                m_IsAllChecked = value;
                foreach (var item in GPData)
                {
                    item.IsChecked = m_IsAllChecked;
                }
                this.RaisePropertyChanged();
            }
        }

        #region 构造方法

        public MainViewModel(MainWindow view)
        {
            synContent = System.Threading.SynchronizationContext.Current;
            m_View = view;
            DataHelper.GetConfigData();
            if (m_View.m_ViewType == 1)
            {
                view.m_Time = DateTime.Now.Date.ToShortDateString();
                //System.Threading.Thread thread = new System.Threading.Thread(InitDataForOldGps);
                //thread.IsBackground = true;
                //thread.Start();

                System.Threading.Thread thread = new System.Threading.Thread(() =>
                {
                    Stopwatch stopwatch = new Stopwatch();
                    while (m_View != null)
                    {
                        stopwatch.Restart();
                        InitDataForOldGps();

                        while (stopwatch.ElapsedMilliseconds < 10000)
                        {
                            System.Threading.Thread.Sleep(500);
                        }
                    }
                });
                thread.IsBackground = true;
                thread.Start();
            }
            else if (m_View.m_ViewType == 2)
            {
                //System.Threading.Thread thread = new System.Threading.Thread(InitDataForLockGps);
                //thread.IsBackground = true;
                //thread.Start();
                System.Threading.Thread thread = new System.Threading.Thread(() =>
                {
                    Stopwatch stopwatch = new Stopwatch();
                    while (m_View != null)
                    {
                        stopwatch.Restart();
                        InitDataForLockGps();

                        while (stopwatch.ElapsedMilliseconds < 10000)
                        {
                            System.Threading.Thread.Sleep(500);
                        }
                    }
                });
                thread.IsBackground = true;
                thread.Start();
            }
            else if(m_View.m_ViewType == 3)
            {
                //System.Threading.Thread thread = new System.Threading.Thread(InitHighChanceGps);
                //thread.IsBackground = true;
                //thread.Start();
                SelectedTime = DateTime.Now;
                System.Threading.Thread thread = new System.Threading.Thread(() =>
                {
                    Stopwatch stopwatch = new Stopwatch();
                    while (m_View != null)
                    {
                        stopwatch.Restart();
                        InitHighChanceGps();

                        while (stopwatch.ElapsedMilliseconds < 10000)
                        {
                            System.Threading.Thread.Sleep(500);
                        }
                    }
                });
                thread.IsBackground = true;
                thread.Start();
            }
            else
            {
                worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;
                worker.ProgressChanged += Worker_ProgressChanged;
                worker.RunWorkerCompleted += Worker_RunWorkerCompleted;

                InitYestodayTopData();

                //InitData();

                //dispatcherTimer.Interval = TimeSpan.FromMilliseconds(3000);
                //dispatcherTimer.Tick -= FlashData;
                //dispatcherTimer.Tick += FlashData;
                //dispatcherTimer.Start();

                //System.Threading.Thread thread = new System.Threading.Thread(FlashData);
                System.Threading.Thread thread = new System.Threading.Thread(() =>
                {
                    Stopwatch stopwatch = new Stopwatch();
                    while (m_View != null)
                    {
                        stopwatch.Restart();
                        FlashData();

                        while (stopwatch.ElapsedMilliseconds < 3000)
                        {
                            System.Threading.Thread.Sleep(500);
                        }
                    }
                });
                thread.IsBackground = true;
                thread.Start();

                //一分钟获取一次数据
                backDataTimer.Interval = 1000;
                backDataTimer.Elapsed -= SufferData;
                backDataTimer.Elapsed += SufferData;
                backDataTimer.Start();

            }
        }
        #endregion

        #region 进度条相关
        private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            m_View.progressBar.Value = 0;
            m_View.barText.Text = "";
        }

        private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            m_View.progressBar.Value = e.ProgressPercentage;

            int currentTask = (int)e.UserState;
            m_View.barText.Text = $"正在{AlGpHelper.InfoMsg}（{currentTask}/{AlGpHelper.HistoryGpNum}）";
        }

        public void Worker_DoWork_LoadHis(object sender, DoWorkEventArgs e)
        {
            AlGpHelper.LoadHistoryGpInfo(worker);
        }
        public void Worker_DoWork_ImportHis5MS(object sender, DoWorkEventArgs e)
        {
            AlGpHelper.ImportHistory5MSInfo(SelectedFiles.ToList(), worker);
        }
        public void Worker_DoWork_ImportHis1MS(object sender, DoWorkEventArgs e)
        {
            AlGpHelper.ImportHistory1MSInfo(SelectedFiles.ToList(), worker);
        }
        public void Worker_DoWork_GetGoUpMostGPs(object sender, DoWorkEventArgs e)
        {

        }
        public void Worker_DoWork_Test(object sender, DoWorkEventArgs e)
        {
            Test.Run(worker);
        }
        #endregion

        #region 业务方法
        /// <summary>
        /// 根据时间初始化历史数据
        /// </summary>
        /// <param name="time"></param>
        public void InitDataForOldGps()
        {
            DateTime now = DateTime.Now;
            DateTime tdStopTime = now.Date + ConfigData.GpStopTime;

            if (ConfigData.MidFastUpGPs.ContainsKey(m_View.m_Time))
            {
                int index = 1;
                var gps = ConfigData.MidFastUpGPs[m_View.m_Time];

                if(m_View.m_Time != now.ToShortDateString() ||
                    DateTime.Compare(now, tdStopTime) > 0)
                {
                    List<ViewEntity> list = new List<ViewEntity>();
                    foreach (var item in gps)
                    {
                        ViewEntity ent = new ViewEntity();
                        ent.Code = item.Code;
                        ent.Name = item.Name;
                        ent.Num = index++;
                        ent.CurPrice = item.EndPrice;
                        ent.CurMarkUp = item.EndMarkUp;
                        ent.RecordTime = item.RecordTime.ToString();
                        ent.RecordPrice = item.RecordPrice;
                        ent.RecordMarkUp = item.RecordMarkUp;

                        list.Add(ent);
                    }
                    synContent.Post(FlashViewData, list);
                    return;
                }
                var urls = UrlHelper.GetUrlForAllRealTimeData();

                List<ViewEntity> ents = new List<ViewEntity>();
                foreach (var url in urls)
                {
                    ents.AddRange(GetGPData(url).Result);
                }
                List<ViewEntity> list1 = new List<ViewEntity>();

                foreach (var gp in gps)
                {
                    var ent = ents.Find(x => x.Code == gp.Code);
                    if(ent != null)
                    {
                        ent.Num = index++;
                        ent.RecordTime = gp.RecordTime.ToString();
                        ent.RecordPrice = gp.RecordPrice;
                        ent.RecordMarkUp = gp.RecordMarkUp;
                        list1.Add(ent);
                    }
                }
                synContent.Post(FlashViewData, list1);

            }
        }
        /// <summary>
        /// 初始化自选数据
        /// </summary>
        public void InitDataForLockGps()
        {
            DateTime now = DateTime.Now;
            DateTime tdStopTime = now.Date + ConfigData.GpStopTime;

            int index = 1;
            if (DateTime.Compare(now, tdStopTime) > 0
    && ConfigData.LockGpDataInfo != null
    && ConfigData.LockGpDataInfo.Count > 0
    && ConfigData.LockGpDataInfo.Count == ConfigData.LockGPs.Count)
            {
                bool isSame = true;
                foreach (var item in ConfigData.LockGPs)
                {
                    if(ConfigData.LockGpDataInfo.Find(x => x.Code == item) == null)
                    {
                        isSame = false;
                        break;
                    }
                }
                if (isSame)
                {
                    synContent.Post(FlashViewData, ConfigData.LockGpDataInfo);

                    //GPData = new ObservableCollection<ViewEntity>(ConfigData.LockGpDataInfo);
                    return;
                }
            }
            var urls = UrlHelper.GetUrlForAllRealTimeData();

            List<ViewEntity> ents = new List<ViewEntity>();
            foreach (var url in urls)
            {
                ents.AddRange(GetGPData(url).Result);
            }
            List<ViewEntity> list = new List<ViewEntity>();

            foreach (var code in ConfigData.LockGPs)
            {
                var ent = ents.Find(x => x.Code == code);
                if(ent != null)
                {
                    ent.Num = index++;
                    list.Add(ent);
                }
            }
            ConfigData.LockGpDataInfo = new List<ViewEntity>(list);
            synContent.Post(FlashViewData, list);

        }
        /// <summary>
        /// 初始化高机会股
        /// </summary>
        public void InitHighChanceGps()
        {
            DateTime tdStopTime = SelectedTime + ConfigData.GpStopTime;

            int index = 1;
            var codes = GpLocalDataHelper.GetValidGpCodes();
            List<string> highList = new List<string>();

            //历史数据分析
            if (SelectedTime.Year != DateTime.Now.Year ||
   SelectedTime.Month != DateTime.Now.Month ||
   SelectedTime.Day != DateTime.Now.Day)
            {
                List<ViewEntity> localList = new List<ViewEntity>();
                int indexNum = 1;
                foreach (var item in codes)
                {
                    if (item == "002238")
                    {
                        int a = 0;
                    }
                    var isHigh = AlGpHelper.HasHighChance2(item, SelectedTime, IsCheckPrePrice,out GpDayEntity dayEnt);
                    if (isHigh &&　dayEnt != null)
                    {
                        ViewEntity ent = new ViewEntity();
                        ent.Num = indexNum++;
                        ent.Code = dayEnt.Code;
                        ent.Name = dayEnt.Name;
                        ent.CurPrice = IsCheckPrePrice ? dayEnt.PrePrice : dayEnt.ClsPrice;
                        ent.CurMarkUp = (dayEnt.PrePrice - dayEnt.ClsPrice / (dayEnt.MarkUp / 100 + 1)) / (dayEnt.ClsPrice / (dayEnt.MarkUp / 100 + 1));
                        ent.CurMarkUp = (float)Math.Round(ent.CurMarkUp * 100, 2, MidpointRounding.AwayFromZero);
                        localList.Add(ent);
                    }
                }
                synContent.Post(FlashViewData, localList);

                return;
            }

            foreach (var item in codes)
            {
                var isHigh = AlGpHelper.HasHighChance2(item);
                if (isHigh)
                {
                    highList.Add(item);
                }
            }

            if (DateTime.Compare(SelectedTime, tdStopTime) > 0
    && ConfigData.HighGpDataInfo != null
    && ConfigData.HighGpDataInfo.Count > 0)
            {
                bool isSame = true;
                //foreach (var item in highList)
                //{
                //    if (ConfigData.HighGpDataInfo.Find(x => x.Code == item) == null)
                //    {
                //        isSame = false;
                //        break;
                //    }
                //}
                if (isSame)
                {
                    synContent.Post(FlashViewData, ConfigData.HighGpDataInfo);

                    //GPData = new ObservableCollection<ViewEntity>(ConfigData.HighGpDataInfo);
                    return;
                }
            }

            var urls = UrlHelper.GetUrlForAllRealTimeData();

            List<ViewEntity> ents = new List<ViewEntity>();
            foreach (var url in urls)
            {
                ents.AddRange(GetGPData(url).Result);
            }
            List<ViewEntity> list = new List<ViewEntity>();

            foreach (var code in highList)
            {
                var ent = ents.Find(x => x.Code == code);
                if (ent != null && ent.CurMarkUp >= 3)
                {
                    ent.Num = index++;
                    list.Add(ent);
                }
            }
            ConfigData.HighGpDataInfo = new List<ViewEntity>(list);
            synContent.Post(FlashViewData, list);

        }
        private void FlashViewData(object obj)
        {
            GPData = new ObservableCollection<ViewEntity>(obj as List<ViewEntity>);
            if(GPData.Count == 0)
            {
                GPData.Add(new ViewEntity { Name = "无数据" });
            }
        }
        /// <summary>
        /// 初始化实时数据
        /// </summary>
        public void InitData()
        {
            InitYestodayTopData();
            FlashData();
        }
        /// <summary>
        /// 初始化昨日涨停数据
        /// </summary>
        private void InitYestodayTopData()
        {
            DateTime tempTime = DateTime.Now;
            var tuple = m_View.GetTopData(tempTime, false).Result;
            if(tuple == null)
            {
                tempTime = tempTime.AddDays(-1);
                tuple = m_View.GetTopData(tempTime, true).Result;
                while (tuple == null)
                {
                    tempTime = tempTime.AddDays(-1);
                    tuple = m_View.GetTopData(tempTime, true).Result;
                }
                tuple = m_View.GetTopData(tempTime, true, tuple.Item1).Result;
            }
            else
            {
                tuple = m_View.GetTopData(tempTime, false, tuple.Item1).Result;
            }

            ConfigData.YestodayTopGps.Clear();
            ConfigData.YestodayTopGps.AddRange(tuple.Item2.Select(x => x.Code));
        }

        private bool IsResponsing = false;
        /// <summary>
        /// 实时刷新数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void FlashData()
        {
            if (IsResponsing)
                return;
            string url = url1ForACCER;
            if (OrderBy == SortType.ACCERInFive)
            {
                url = url1ForACCERInFive;
            }

            try
            {
                IsResponsing = true;

                var ents = GetGPData(url, 10).Result;
                //var ents = GetGPData1(url, 3000, 10000).Result;
                if (OrderBy == SortType.ACCER)
                {
                    ents = ents.OrderByDescending(x => x.CurAccer).ToList();
                }
                else
                {
                    ents = ents.OrderByDescending(x => x.CurAccerInFive).ToList();
                }

                for (int i = 0; i < ents.Count; i++)
                {
                    if (!CommonHelper.IsValidCode(ents[i].Code, ents[i].Name))
                    {
                        ents.RemoveAt(i--);
                        continue;
                    }
                    if (ents[i].CurPrice > ConfigData.MaxPrice)
                    {
                        ents.RemoveAt(i--);
                        continue;
                    }
                    if (ents[i].CurMarkValue < ConfigData.MinMarkValue)
                    {
                        ents.RemoveAt(i--);
                        continue;
                    }
                    if (ConfigData.FlagGps.Contains(ents[i].Name))
                    {
                        ents.RemoveAt(i--);
                        continue;
                    }
                    ents[i].IsLock = ConfigData.LockGPs.Contains(ents[i].Code);
                    ents[i].IsYestodayTop = ConfigData.YestodayTopGps.Contains(ents[i].Code);

                    if(ConfigData.IsFst1PlateMode)
                    {
                        if(ents[i].IsYestodayTop || ents[i].CurMarkUp <= 5.0)
                        {
                            ents.RemoveAt(i--);
                            continue;
                        }
                    }
                }
                int index = 1;
                ents.ForEach(x => x.Num = index++);

                GetMidUpGp(ents);

                GPData = new ObservableCollection<ViewEntity>(ents);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
                IsResponsing = false;

            }
            IsResponsing = false;
        }
        /// <summary>
        /// 缓存实时数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SufferData(object sender, ElapsedEventArgs e)
        {
            if (!ConfigData.IsBackgroundDataBufferEnable) return;
            DateTime now = DateTime.Now;

            DateTime tdStartTime = now.Date + ConfigData.GpStartTime;
            DateTime tdStopTime = now.Date + ConfigData.GpStopTime;
            if (DateTime.Compare(now, tdStartTime) <= 0
                || DateTime.Compare(now, tdStopTime) > 0)
                return;
            var urls = UrlHelper.GetUrlForAllRealTimeData();

            List<ViewEntity> ents = new List<ViewEntity>();
            foreach (var url in urls)
            {
                ents.AddRange(GetGPData(url).Result);
            }
            foreach (var item in ents)
            {
                if (ConfigData.TotalGpSufferData.ContainsKey(item.Code))
                {
                    ConfigData.TotalGpSufferData[item.Code].Add(item.CurMarkUp);
                }
                else
                {
                    ConfigData.TotalGpSufferData.Add(item.Code, new List<double> { item.CurMarkUp });
                }
            }
        }
        /// <summary>
        /// 根据代号获取实时分时数据
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private async Task<List<DetailEntity>> GetDetailData(string code)
        {
            List<DetailEntity> prices = new List<DetailEntity>();
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    HttpResponseMessage response = await client.GetAsync(UrlHelper.GetUrlForSingleDetailData(code)).ConfigureAwait(false);
                    if (response.IsSuccessStatusCode)
                    {
                        response.EnsureSuccessStatusCode();
                        string htmlContent = response.Content.ReadAsStringAsync().Result;
                        if (!string.IsNullOrEmpty(htmlContent))
                        {
                            JObject jobject = JObject.Parse(htmlContent);
                            var PrePrice = double.Parse(jobject["data"]["prePrice"].ToString());
                            var Name = jobject["data"]["name"].ToString();
                            var trends = jobject["data"]["trends"].Children();
                            int index = 1;
                            foreach (var item in trends)
                            {
                                var strs = item.ToString().Split(',');
                                if (strs.Count() == 8)
                                {
                                    DetailEntity ent = new DetailEntity();
                                    var datesStr = strs[0].Split(' ');
                                    var dates = datesStr[0].Split('-');
                                    var times = datesStr[1].Split(':');
                                    ent.EntTimeSpan = new DateTime(int.Parse(dates[0]), int.Parse(dates[1]), int.Parse(dates[2]), int.Parse(times[0]), int.Parse(times[1]), 0);
                                    ent.Price = double.Parse(strs[2]);
                                    double markUp = (ent.Price - PrePrice) / PrePrice * 100.00;
                                    ent.MarkUp = Math.Round(markUp, 2, MidpointRounding.AwayFromZero);
                                    ent.Index = index++;
                                    prices.Add(ent);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return prices;
        }
        /// <summary>
        /// 获取实时数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private async Task<List<ViewEntity>> GetGPData(string url,int timeOutMs = 60)
        {
            List<ViewEntity> ents = new List<ViewEntity>();
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.Timeout = new TimeSpan(0, 0, timeOutMs);
                    HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
                    if (response.IsSuccessStatusCode)
                    {
                        response.EnsureSuccessStatusCode();
                        string htmlContent = response.Content.ReadAsStringAsync().Result;
                        if (!string.IsNullOrEmpty(htmlContent))
                        {
                            JObject jobject = JObject.Parse(htmlContent);
                            var childrens = jobject["data"]["diff"].Children();
                            string totalStr = jobject["data"]["total"].ToString();
                            if (!string.IsNullOrEmpty(totalStr))
                            {
                                int.TryParse(totalStr, out CommonData.TotalGpCount);
                            }

                            foreach (var item in childrens)
                            {
                                ViewEntity ent = new ViewEntity();
                                ent.Code = item["f12"].ToString();
                                ent.Name = item["f14"].ToString();
                                ent.CurPrice = float.TryParse(item["f2"].ToString(), out float curPrice) ? curPrice : 0.0f;
                                ent.CurMarkUp = float.TryParse(item["f3"].ToString(), out float curMarkup) ? curMarkup : 0.0f;
                                ent.CurAccer = float.TryParse(item["f22"].ToString(), out float curAccer) ? curAccer : 0.0f;
                                ent.CurAccerInFive = float.TryParse(item["f11"].ToString(), out float curAccerInFive) ? curAccerInFive : 0.0f;
                                ent.CurMarkValue = double.TryParse(item["f20"].ToString(), out double curMarkValue) ? curMarkValue / 100000000.00 : 0.0;
                                ents.Add(ent);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {

            }

            return ents;
        }

        /// <summary>
        /// 获取单个股数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        //f43 收盘价  f44 最高价  f45 最低价  f46 今天开盘价  f57 code  f58 name  f169 涨跌价 f170 涨跌幅
        private async Task<ViewEntity> GetGPDataFOrOne(string url)
        {
            ViewEntity ent = new ViewEntity();
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
                if (response.IsSuccessStatusCode)
                {
                    response.EnsureSuccessStatusCode();
                    string htmlContent = response.Content.ReadAsStringAsync().Result;
                    if (!string.IsNullOrEmpty(htmlContent))
                    {
                        JObject jobject = JObject.Parse(htmlContent);
                        
                        ent.Code = jobject["data"]["f57"].ToString();
                        ent.Name = jobject["data"]["f58"].ToString();
                        ent.CurPrice = float.TryParse(jobject["data"]["f43"].ToString(), out float curPrice) ? curPrice : 0.0f;
                        ent.CurMarkUp = float.TryParse(jobject["data"]["f170"].ToString(), out float curMarkup) ? curMarkup : 0.0f;
                        ent.HighPrice = double.TryParse(jobject["data"]["f44"].ToString(), out double highPrice) ? highPrice : 0.0;
                        ent.LowPrice = double.TryParse(jobject["data"]["f45"].ToString(), out double lowPrice) ? lowPrice : 0.0;
                        ent.PrePrice = double.TryParse(jobject["data"]["f46"].ToString(), out double prePrice) ? prePrice : 0.0;
                    }
                }
            }
            return ent;
        }
        /// <summary>
        /// 实时数据处理(涨幅，优股，其他)
        /// </summary>
        /// <param name="GPList"></param>
        private void GetMidUpGp(List<ViewEntity> GPList)
        {
            DateTime now = DateTime.Now;
            DateTime tdTargetStartTime = now.Date + ConfigData.GPStartRecordTime;
            DateTime tdTargetEndTime = now.Date + ConfigData.GPEndRecordTime;
            DateTime tdStopTime = now.Date + ConfigData.GpStopTime;

            List<MidFastTopGpEntity> midFastGpsList = new List<MidFastTopGpEntity>();
            if (ConfigData.MidFastUpGPs.ContainsKey(now.Date.ToShortDateString()))
            {
                midFastGpsList = ConfigData.MidFastUpGPs[now.Date.ToShortDateString()];
            }
            else
            {
                ConfigData.MidFastUpGPs.Add(now.Date.ToShortDateString(), midFastGpsList);
            }

            List<string> analyseGpsList = new List<string>();
            if (ConfigData.AnalyseGPs.ContainsKey(now.Date.ToShortDateString()))
            {
                analyseGpsList = ConfigData.AnalyseGPs[now.Date.ToShortDateString()];
            }
            else
            {
                ConfigData.AnalyseGPs.Add(now.Date.ToShortDateString(), analyseGpsList);
            }

            if (DateTime.Compare(now, tdTargetStartTime) > 0
                && DateTime.Compare(now, tdTargetEndTime) < 0)
            {
                foreach (var item in GPList)
                {
                    if(OrderBy == SortType.ACCER)
                    {
                        if (item.CurAccer >= ConfigData.MinACCER
                             && (!ConfigData.IsFilterGps || (ConfigData.IsFilterGps && item.CurMarkUp >= ConfigData.MinMarkUpForMidFast)))
                        {
                            if (midFastGpsList.Find(x => x.Code == item.Code) == null)
                            {
                                MidFastTopGpEntity ent = new MidFastTopGpEntity();
                                ent.Code = item.Code;
                                ent.Name = item.Name;
                                ent.RecordTime = DateTime.Now;
                                ent.RecordPrice = item.CurPrice;
                                ent.RecordMarkUp = item.CurMarkUp;
                                if (!(float.IsNaN(ent.RecordPrice) || float.IsNaN(ent.RecordMarkUp)
                                    || float.IsNaN(ent.RecordMarkUp) || float.IsNaN(ent.RecordMarkUp)))
                                    midFastGpsList.Add(ent);
                            }
                        }
                        bool isSucc = SelectAnaylseGp(item, item.CurAccer);
                        item.IsAnalyseGp = isSucc;
                        //if (item.IsAnalyseGp)
                        //{
                        //    if (!ConfigData.LockGPs.Contains(item.Code))
                        //    {
                        //        ConfigData.LockGPs.Add(item.Code);
                        //    }
                        //}
                        //string filePath = "HistoryInfo//" + DateTime.Now.Year + "//" + item.Code + ".json";
                        //if (File.Exists(filePath))
                        //{
                        //    string json = File.ReadAllText(filePath);
                        //    var strs = json.Split(';');
                        //    List<GpDayEntity> list = new List<GpDayEntity>();
                        //    foreach (var str in strs)
                        //    {
                        //        var ent = GpDayEntity.Create(str);
                        //        if(ent != null)
                        //            list.Add(ent);
                        //    }
                        //    bool isHigh = AlGpHelper.HasHighChance(item.Code, list);
                        //    item.IsHighGp = isHigh;
                        //    isSucc = isHigh || isSucc;
                        //}
                        if (isSucc)
                        {
                            if (analyseGpsList.Find(x => x == item.Code) == null)
                            {
                                analyseGpsList.Add(item.Code);
                            }
                        }
                    }
                    else
                    {
                        if (item.CurAccerInFive >= ConfigData.MinACCER
                             && (!ConfigData.IsFilterGps || (ConfigData.IsFilterGps && item.CurMarkUp >= ConfigData.MinMarkUpForMidFast)))
                        {
                            if (midFastGpsList.Find(x => x.Code == item.Code) == null)
                            {
                                MidFastTopGpEntity ent = new MidFastTopGpEntity();
                                ent.Code = item.Code;
                                ent.Name = item.Name;
                                ent.RecordTime = DateTime.Now;
                                ent.RecordPrice = item.CurPrice;
                                ent.RecordMarkUp = item.CurMarkUp;
                                midFastGpsList.Add(ent);
                            }
                        }
                        //bool isSucc = SelectAnaylseGp(item, item.CurAccerInFive);
                        //item.IsAnalyseGp = isSucc;
                        //string filePath = "HistoryInfo//" + DateTime.Now.Year + "//" + item.Code + ".json";
                        //if (File.Exists(filePath))
                        //{
                        //    string json = File.ReadAllText(filePath);
                        //    var strs = json.Split(';');
                        //    List<GpDayEntity> list = new List<GpDayEntity>();
                        //    foreach (var str in strs)
                        //    {
                        //        var ent = GpDayEntity.Create(str);
                        //        if (ent != null)
                        //            list.Add(ent);
                        //    }
                        //    bool isHigh = AlGpHelper.HasHighChance(item.Code, list);
                        //    item.IsHighGp = isHigh;
                        //    isSucc = isHigh || isSucc;
                        //}
                        //if (isSucc)
                        //{
                        //    if (analyseGpsList.Find(x => x == item.Code) == null)
                        //    {
                        //        analyseGpsList.Add(item.Code);
                        //    }
                        //}
                    }

                    bool isHigh = AlGpHelper.HasHighChance2(item.Code, item.CurPrice, item.CurMarkUp);
                    item.IsHighGp = isHigh && item.CurMarkUp >= 3;
                    if (item.IsHighGp &&　item.CurMarkUp > 5)
                    {
                        //if (!ConfigData.LockGPs.Contains(item.Code))
                        //{
                        //    ConfigData.LockGPs.Add(item.Code);
                        //}
                    }
                }
            }
            else if(DateTime.Compare(now, tdStopTime) > 0 && !hasWrited)
            {
                hasWrited = true;
                var urls = UrlHelper.GetUrlForAllRealTimeData();

                GPList = new List<ViewEntity>();
                foreach (var url in urls)
                {
                    GPList.AddRange(GetGPData(url).Result);
                }
                for (int i = 0; i < midFastGpsList.Count; i++)
                {
                    var temp = GPList.Find(x => x.Code == midFastGpsList[i].Code);
                    if(temp != null)
                    {
                        if(ConfigData.IsMinMarkUpForLocalEnable && temp.CurMarkUp < ConfigData.MinMarkUpForLocal)
                        {
                            midFastGpsList.RemoveAt(i--);
                        }
                        midFastGpsList[i].EndPrice = temp.CurPrice;
                        midFastGpsList[i].EndMarkUp = temp.CurMarkUp;
                    }
                }
                //m_View.LoadHistoryDataItem_Click(null, null);
                if (MessageBox.Show("确定要加载历史数据吗？", "提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                {
                    synContent.Post(m_View.LoadHistoryExec, null);
                    //ClearWorkerHandler();
                    //worker.DoWork += Worker_DoWork_LoadHis;
                    //worker.RunWorkerAsync();
                }
                //ReflashHistoryDayInfo();
                //盘后加载历史数据
                //worker.RunWorkerAsync();
            }
        }
        /// <summary>
        /// 筛选优股
        /// </summary>
        /// <param name="gp"></param>
        private bool SelectAnaylseGp(ViewEntity gp,double accer)
        {
            if (accer >= ConfigData.MinACCER && gp.CurMarkUp >= ConfigData.MinMarkUpForMidFast)
            {
                DateTime nowTime = DateTime.Now;
                DateTime tdStartTime = nowTime.Date + ConfigData.GpStartTime + new TimeSpan(0,5,0);
                DateTime tdStopTime = nowTime.Date + ConfigData.GpStopTime;
                DateTime tdMidStopTime = nowTime.Date + ConfigData.GpMidStopTime;
                DateTime tdMidStartTime = nowTime.Date + ConfigData.GpMidStartTime;
                int count = 0;
                if (DateTime.Compare(nowTime, tdStartTime) > 0 && DateTime.Compare(nowTime, tdMidStopTime) <= 0)
                {
                    var timeSpan = nowTime - tdStartTime;
                    count = timeSpan.Hours * 60 + timeSpan.Minutes;
                }
                else if(DateTime.Compare(nowTime, tdMidStopTime) > 0 && DateTime.Compare(nowTime, tdMidStartTime) <= 0)
                {
                    var timeSpan = tdMidStopTime - tdStartTime;
                    count = timeSpan.Hours * 60 + timeSpan.Minutes;
                }
                else if (DateTime.Compare(nowTime, tdMidStartTime) > 0 && DateTime.Compare(nowTime, tdStopTime) <= 0)
                {
                    var timeSpan = nowTime - tdMidStartTime;
                    count = timeSpan.Hours * 60 + timeSpan.Minutes;
                    timeSpan = tdMidStopTime - tdStartTime;
                    count += timeSpan.Hours * 60 + timeSpan.Minutes;
                }
                if (!ConfigData.TotalGpSufferData.ContainsKey(gp.Code))
                {
                    var res = GetDetailData(gp.Code).Result;
                    ConfigData.TotalGpSufferData.Add(gp.Code, res.Select(x => x.MarkUp).ToList());
                }
                else if(ConfigData.TotalGpSufferData[gp.Code].Count < count - 2)
                {
                    var res = GetDetailData(gp.Code).Result;
                    ConfigData.TotalGpSufferData[gp.Code].Clear();
                    ConfigData.TotalGpSufferData[gp.Code] = res.Select(x => x.MarkUp).ToList();
                }

                if (ConfigData.TotalGpSufferData.ContainsKey(gp.Code)
                    && ConfigData.TotalGpSufferData[gp.Code].Count > 20)
                {
                    var list = new List<double>(ConfigData.TotalGpSufferData[gp.Code]);
                    list.RemoveRange(list.Count - 5, 5);
                    //list.RemoveRange(list.Count - 2, 2);
                    list.RemoveRange(0, 10);
                    if(list.Max() - list.Min() < 3 && gp.CurMarkUp >= list.Max())
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public void ClearWorkerHandler()
        {
            worker.DoWork -= Worker_DoWork_LoadHis;
            worker.DoWork -= Worker_DoWork_ImportHis5MS;
            worker.DoWork -= Worker_DoWork_ImportHis1MS;
            worker.DoWork -= Worker_DoWork_Test;
        }

        public void UpdateGpListExecute()
        {
            try
            {
                var urls = UrlHelper.GetUrlForAllRealTimeData();

                List<ViewEntity> ents = new List<ViewEntity>();
                foreach (var url in urls)
                {
                    ents.AddRange(GetGPData(url).Result);
                }
                StringBuilder sbAll = new StringBuilder();
                StringBuilder sbValid = new StringBuilder();

                foreach (var item in ents)
                {
                    string str = item.Code + ":" + item.Name;
                    sbAll.Append(str + ";");
                    if (CommonHelper.IsValidCode(item.Code, item.Name))
                        sbValid.Append(str + ";");
                }
                File.WriteAllText(CommonData.AllCodeFilePath, sbAll.ToString().TrimEnd(';'));
                File.WriteAllText(CommonData.CodeFilePath, sbValid.ToString().TrimEnd(';'));
                MessageBox.Show("更新成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }
        #endregion
    }

    /// <summary>
    /// 界面对象
    /// </summary>
    public class ViewEntity : BindableBase
    {
        private int m_Num;

        public int Num
        {
            get { return m_Num; }
            set 
            { 
                m_Num = value;
                RaisePropertyChanged();
            }
        }
        private string m_Code;

        public string Code
        {
            get { return m_Code; }
            set
            {
                m_Code = value;
                RaisePropertyChanged();
            }
        }
        private string m_Name;

        public string Name
        {
            get { return m_Name; }
            set
            {
                m_Name = value;
                RaisePropertyChanged();
            }
        }
        private float m_CurPrice;

        public float CurPrice
        {
            get { return m_CurPrice; }
            set
            {
                m_CurPrice = value;
                RaisePropertyChanged();
            }
        }
        private float m_CurMarkUp;
        /// <summary>
        /// 涨幅
        /// </summary>
        public float CurMarkUp
        {
            get { return m_CurMarkUp; }
            set
            {
                m_CurMarkUp = value;
                RaisePropertyChanged();
            }
        }
        private float m_CurAccer;
        /// <summary>
        /// 涨速
        /// </summary>
        public float CurAccer
        {
            get { return m_CurAccer; }
            set
            {
                m_CurAccer = value;
                RaisePropertyChanged();
            }
        }
        private float m_CurAccerInFive;
        /// <summary>
        /// 五分钟涨速
        /// </summary>
        public float CurAccerInFive
        {
            get { return m_CurAccerInFive; }
            set
            {
                m_CurAccerInFive = value;
                RaisePropertyChanged();
            }
        }

        private bool m_IsAnalyseGp;
        /// <summary>
        /// 优股
        /// </summary>
        public bool IsAnalyseGp
        {
            get { return m_IsAnalyseGp; }
            set
            {
                m_IsAnalyseGp = value;
                RaisePropertyChanged();
            }
        }

        private bool m_IsHighGp;
        /// <summary>
        /// 高概率股
        /// </summary>
        public bool IsHighGp
        {
            get { return m_IsHighGp; }
            set
            {
                m_IsHighGp = value;
                RaisePropertyChanged();
            }
        }

        private bool m_IsYestodayTop;
        /// <summary>
        /// 昨日涨停
        /// </summary>
        public bool IsYestodayTop
        {
            get { return m_IsYestodayTop; }
            set
            {
                m_IsYestodayTop = value;
                RaisePropertyChanged();
            }
        }

        private bool m_IsLock = false;
        /// <summary>
        /// 是否是自选
        /// </summary>
        public bool IsLock
        {
            get { return m_IsLock; }
            set
            {
                m_IsLock = value;
                RaisePropertyChanged();
            }
        }

        private bool m_IsChecked = false;
        /// <summary>
        /// 是否选中
        /// </summary>
        public bool IsChecked
        {
            get { return m_IsChecked; }
            set
            {
                m_IsChecked = value;
                RaisePropertyChanged();
            }
        }

        private double m_CurMarkValue;
        /// <summary>
        /// 市值
        /// </summary>
        public double CurMarkValue
        {
            get { return m_CurMarkValue; }
            set
            {
                m_CurMarkValue = value;
                RaisePropertyChanged();
            }
        }
        private System.Windows.Media.Brush m_BackColor = new SolidColorBrush(Colors.White);

        public System.Windows.Media.Brush BackColor
        {
            get 
            {
                //if (IsHighGp)
                //    return new SolidColorBrush(Colors.Pink);
                if (m_CurAccer > ConfigData.MinACCER)
                {
                    //if (IsAnalyseGp)
                    //    return new SolidColorBrush(Colors.Orange);
                    return new SolidColorBrush(Colors.Red);
                }
                else
                {
                    return new SolidColorBrush(Colors.White);
                }
            }
            set
            {
                m_BackColor = value;
                RaisePropertyChanged();
            }
        }
        private System.Windows.Media.Brush m_BackColorInFive = new SolidColorBrush(Colors.White);

        public System.Windows.Media.Brush BackColorInFive
        {
            get
            {
                if (m_CurAccerInFive > ConfigData.MinACCER)
                {
                    if (IsHighGp)
                        return new SolidColorBrush(Colors.Blue);
                    if (IsAnalyseGp)
                        return new SolidColorBrush(Colors.Orange);
                    return new SolidColorBrush(Colors.Red);
                }
                else
                {
                    return new SolidColorBrush(Colors.White);
                }
            }
            set
            {
                m_BackColorInFive = value;
                RaisePropertyChanged();
            }
        }
        private System.Windows.Media.Brush m_BackColorForMarkUp = new SolidColorBrush(Colors.White);

        public System.Windows.Media.Brush BackColorForMarkUp
        {
            get
            {
                if (m_CurMarkUp >= 0)
                {
                    return new SolidColorBrush(Colors.Red);
                }
                else
                {
                    return new SolidColorBrush(Colors.LightGreen);
                }
            }
            set
            {
                m_BackColorForMarkUp = value;
                RaisePropertyChanged();
            }
        }

        private System.Windows.Media.Brush m_StatusColor = new SolidColorBrush(Colors.White);

        public System.Windows.Media.Brush StatusColor
        {
            get
            {
                if (IsHighGp)
                    return new SolidColorBrush(Colors.Pink);
                if (IsAnalyseGp)
                    return new SolidColorBrush(Colors.Orange);
                return new SolidColorBrush(Colors.White);
            }
            set
            {
                m_StatusColor = value;
                RaisePropertyChanged();
            }
        }

        private double m_HighPrice;
        /// <summary>
        /// 最高价
        /// </summary>
        public double HighPrice
        {
            get { return m_HighPrice; }
            set { m_HighPrice = value; }
        }

        private double m_LowPrice;
        /// <summary>
        /// 最低价
        /// </summary>
        public double LowPrice
        {
            get { return m_LowPrice; }
            set { m_LowPrice = value; }
        }

        private double m_PrePrice;
        /// <summary>
        /// 开盘价
        /// </summary>
        public double PrePrice
        {
            get { return m_PrePrice; }
            set { m_PrePrice = value; }
        }

        private string m_RecordTime;
        /// <summary>
        /// 记录时间
        /// </summary>
        public string RecordTime
        {
            get { return m_RecordTime; }
            set
            {
                m_RecordTime = value;
                RaisePropertyChanged();
            }
        }

        private float m_RecordPrice;
        /// <summary>
        /// 记录价格
        /// </summary>
        public float RecordPrice
        {
            get { return m_RecordPrice; }
            set
            {
                m_RecordPrice = value;
                RaisePropertyChanged();
            }
        }

        private float m_RecordMarkUp;
        /// <summary>
        /// 记录涨幅
        /// </summary>
        public float RecordMarkUp
        {
            get { return m_RecordMarkUp; }
            set
            {
                m_RecordMarkUp = value;
                RaisePropertyChanged();
            }
        }
    }
}
